package com.example.redisson.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.RedisSerializer;

@Configuration
// 由于我们使用了自定义 RedisCacheManager 缓存管理器，导致默认的 CacheManager 缓存管理器失效，缓存配置文件 CacheProperties 也没有注册到 Spring 容器中，所以需要单独配置。
public class RedisConfig {

    // 默认配置参考 RedisAutoConfiguration 自动配置类
    // Redis 缓存对象内容的序列化不使用 RedisTemplate 的配置，需要在 RedisCacheManager 中单独配置，否则缓存 Cache 对象内容值会乱码
    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(factory);
        redisTemplate.setDefaultSerializer(RedisSerializer.string());
        redisTemplate.setKeySerializer(RedisSerializer.string());
        redisTemplate.setHashKeySerializer(RedisSerializer.string());
        redisTemplate.setValueSerializer(RedisSerializer.json());
        redisTemplate.setHashValueSerializer(RedisSerializer.json());
        return redisTemplate;
    }

}

// springboot 中使用 redis 缓存注解参考官网 https://java.cunzaima.cn/spring-boot_docs_3.2.3-zh-all/io.html#io
// 一个 Cache 缓存的键的组成格式为 prefix + cacheName + key 三部分组成，其中 prefix 为缓存键的前缀，cacheName 就是 @CacheConfig 中配置的 cacheNames，key 就是方法参数或者方法返回值。
// 例如：@Cacheable(cacheNames = "userCache", key = "#userId")，则最终的缓存键为：userCache:12345

// 一个缓存对象在Redis中存储的名称格式是： 前缀 + CacheName:key
// 假如：前缀为 blog_	  CacheName为 userCache 	 key为 12345	  则最终在Redis中存储的名称为： blog_userCache:12345

// 注册 RedisCacheManager 组件相当于配置spring.cache.type=redis	两者只可选其一。不要同时配置，避免造成不必要的冲突。如果同时配置了，会使用自定义的配置。
// 配置了spring.cache.type=redis，Spring Boot会自动创建一个默认的RedisCacheManager bean，并将其用作默认的缓存管理器。